/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 *
 *
 * 注明：参数myFatherFATNumber   可通过索引树 获取下标   凭借一一对应关系   获取对应下标的分配表项的索引
 */

package com.yurendao.OSFileSystem.MyFAT;

import com.yurendao.OSFileSystem.data.*;
import java.util.ArrayList;

import javax.swing.JOptionPane;

import com.yurendao.OSFileSystem.disk.DiskAttributes;
import com.yurendao.OSFileSystem.file.FileAttributes;
import com.yurendao.OSFileSystem.folder.FolderAttributes;
import com.yurendao.OSFileSystem.disk.MyDisk;
import com.yurendao.OSFileSystem.file.MyFile;
import com.yurendao.OSFileSystem.folder.MyFolder;


/**
 *
 * @author Administrator
 */
public class MyFAT {

    private FATStructure[] myfat ;

    public MyFAT() {
        //文件分配表 总共有128个物理块
        this.myfat = new FATStructure[128];
        for(int i=0;i<this.myfat.length;i++){
            this.myfat[i]= new FATStructure();
        }
        //其中 前两个 0、1 用于存储系统用的分配表  不可被用户使用
        this.myfat[0].setFatIndex(DataAttribute.FAT_numberOfEnd);
        this.myfat[0].setFatType(DataAttribute.FAT_aDisk);
        DiskAttributes rootAttributes = new DiskAttributes("MyComputer");
        MyDisk root = new MyDisk(0,0,rootAttributes);
        this.myfat[0].setFatContent(root);
        this.myfat[1].setFatIndex(DataAttribute.FAT_numberOfEnd);
        //初始化 所有物理块都可用
        for(int i=DataAttribute.FAT_startNumber;i<this.myfat.length;i++){
            this.myfat[i].setFatIndex(DataAttribute.FAT_numberOfusable);
        }
    }
    public Boolean isaFile(int type){
        return DataAttribute.FAT_aFile==type? true:false;
    }
    public Boolean isaFolder(int type){
        return DataAttribute.FAT_aFolder==type? true:false;
    }

    //创建 文件     需要指明 文件的实际大小（需要用多少个物理块来存储文件内容）
    //还要指明 文件所在的文件夹或磁盘 既是父目录所在的物理块的块号
    public void createdFile(int myfatherFATNumber,int numberofFAT ,String filedata,FileAttributes aFileAttributes){
        int previous = 0;
        int latter = 0;
        int usableNumber = 0;
        //判断 磁盘中是否有足够的空间用于创建该文件
        for(int i=DataAttribute.FAT_startNumber;i<this.myfat.length;i++){
            if(this.myfat[i].getFatIndex() == DataAttribute.FAT_numberOfusable)
                usableNumber++;
        }
        if(usableNumber<numberofFAT){
            System.out.println("磁盘空间不足，无法保存文件！！！！");
            JOptionPane.showMessageDialog(null, "磁盘空间不足!!!!!!","警告！！",JOptionPane.WARNING_MESSAGE);
        }else{
            //磁盘有足够的空间用于存储
            //找到第一个 空闲的磁盘块
            for (int i = DataAttribute.FAT_startNumber; i < this.myfat.length; i++) {
                if (this.myfat[i].getFatIndex() == DataAttribute.FAT_numberOfusable) {
                    previous = i;
                    MyFile temp = new MyFile(myfatherFATNumber,previous,filedata,aFileAttributes);
                    this.myfat[i].setFatContent(temp);
                    this.myfat[i].setFatType(DataAttribute.FAT_aFile);
                    break;
                }
            }
            //顺序的为该文件 申请磁盘空间  并在文件分配表中穿创建文件的索引
            //previous：前一个索引的盘块号    latter：后一个索引的盘块号
            for (int i = previous+1; i < this.myfat.length; i++){
                //将最后的盘块的索引 记为255
                if(numberofFAT==1){
                    this.myfat[previous].setFatIndex(DataAttribute.FAT_numberOfEnd);
                    break;
                }
                if (this.myfat[i].getFatIndex() == DataAttribute.FAT_numberOfusable){
                    latter = i;
                    this.myfat[previous].setFatIndex(latter);
                    previous = latter;
                    numberofFAT--;
                }
                                  
            }
        }
    }

    //删除 某个文件
    //提供 文件在FAT中的第一个磁盘号
    public void deletedFile(int myFATNumber){
        int previous = 0;
        int later = 0;
        if(myFATNumber>=DataAttribute.FAT_startNumber&&myFATNumber<this.myfat.length){
            previous = myFATNumber;
            later = this.myfat[myFATNumber].getFatIndex();
            this.myfat[myFATNumber] = new FATStructure();
            while(later!=DataAttribute.FAT_numberOfEnd){
                this.myfat[previous].setFatIndex(DataAttribute.FAT_numberOfusable);
                previous = later;
                later = this.myfat[previous].getFatIndex();
            }
            this.myfat[previous].setFatIndex(DataAttribute.FAT_numberOfusable);
            this.myfat[previous].setFatType(0);
        }
    }
public void jianqiefile(int myFATNumber){
     int previous = 0;
        int later = 0;
        if(myFATNumber>=DataAttribute.FAT_startNumber&&myFATNumber<this.myfat.length){
            previous = myFATNumber;
            later = this.myfat[myFATNumber].getFatIndex();
            this.myfat[myFATNumber] = new FATStructure();
            while(later!=DataAttribute.FAT_numberOfEnd){
                this.myfat[previous].setFatIndex(DataAttribute.FAT_numberOfusable);
                previous = later;
                later = this.myfat[previous].getFatIndex();
            }
            this.myfat[previous].setFatIndex(DataAttribute.FAT_numberOfusable);
            this.myfat[previous].setFatType(0);
        }
}
    //暂时只实现 更新文件名
    public void updateFile(int myFATNumber,String name){
        if(myFATNumber>=DataAttribute.FAT_startNumber&&myFATNumber<this.myfat.length){
            FileAttributes temp = ((MyFile)(this.myfat[myFATNumber].getFatContent())).getMyfileAttributes();
            temp.setFileName(name);
        }
    }

    //创建 文件夹     需要指明 文件夹的父目录的索引
    public void createdFolder(int myfatherFATNumber,FolderAttributes myFolderAttributes ){
       MyFolder temp ;
       int myFATNumber = 0;
       int i = 0;
       //判断 分配表中是否有足够空间创建文件夹   并获取下标
       for(i=DataAttribute.FAT_startNumber;i<this.myfat.length;i++){
           if(this.myfat[i].getFatIndex() == DataAttribute.FAT_numberOfusable){
               myFATNumber = i;
               this.myfat[i].setFatIndex(DataAttribute.FAT_numberOfEnd);
               break;
           }
       }
       if(i>=this.myfat.length){
           System.out.println("磁盘空间不足！！！！");
           JOptionPane.showMessageDialog(null, "磁盘空间不足!!!!!!");
       }else{
           temp = new MyFolder(myfatherFATNumber,myFATNumber,myFolderAttributes);
           this.myfat[i].setFatType(DataAttribute.FAT_aFolder);
           this.myfat[i].setFatContent(temp);
       }
    }

    public void deletedFolder(int myFATNumber){
        if(myFATNumber>=DataAttribute.FAT_startNumber&&myFATNumber<this.myfat.length){
            this.myfat[myFATNumber].setFatIndex(0);
            this.myfat[myFATNumber].setFatType(0);
            this.myfat[myFATNumber].setFatContent(null);
        }
    }

    public void jianqiefolder(int myFATNumber){
         if(myFATNumber>=DataAttribute.FAT_startNumber&&myFATNumber<this.myfat.length){
            this.myfat[myFATNumber].setFatIndex(0);
            this.myfat[myFATNumber].setFatType(0);
            this.myfat[myFATNumber].setFatContent(null);
        }
    }
    //暂时只实现 更新文件夹名
    public void updateFolder(int myFATNumber,String name){
        if(myFATNumber>=DataAttribute.FAT_startNumber&&myFATNumber<this.myfat.length){
            FolderAttributes temp = ((MyFolder)(this.myfat[myFATNumber].getFatContent())).getMyfolderAttributes();
            temp.setFolderName(name);
        }
    }

    private void createdDisk(){

    }

    //用于 程序测试
    //显示  当前文件分配表 的情况
    public void showMyFAT(){
        int j;
        for(int i=0;i<this.myfat.length;i++){
            if(i<10){
                System.out.print("00"+i+"\t");
            }else if(i<100){
                System.out.print("0"+i+"\t");
            }else{
                System.out.print(""+i+"\t");
            }
        }
        System.out.println("first");
        for(int i=0;i<this.myfat.length;i++){
            j=this.myfat[i].getFatIndex();
            if(j<10){
                System.out.print("00"+j+"\t");
            }else if(j<100){
                System.out.print("0"+j+"\t");
            }else{
                System.out.print(""+j+"\t");
            }
        }
        System.out.println("end");
    }

    //用于 程序测试
    //显示 某个文件分配表项 所对应的内容
    public String showFile(int myFATNumber ){
        MyFile temp;
        String result = new String();
        if(this.myfat[myFATNumber].getFatIndex()!=DataAttribute.FAT_numberOfusable){
            if(this.myfat[myFATNumber].getFatType() == DataAttribute.FAT_aFile){
                temp = (MyFile)this.myfat[myFATNumber].getFatContent();
                result = result + temp.getMyfatherFATNumber() + "\n";
                result = result + temp.getMyFATNumber() + "\n";
                result = result + temp.getMyfileAttributes().getFileName() + "\n";
                result = result + temp.getMyfileAttributes().getFileLocation() + "\n";
                result = result + temp.getMyfileAttributes().getFileType() + "\n";
                result = result + temp.getMyfileContent() + "\n";
                result = result + temp.getMyfileAttributes().getFileCreatedTime() + "\n";
            }          
        }
        return result;
    }
    //对外的应用
    //用于 搜索 某个文件夹内的所有文件
    //返回 ArrayList<FATStructure>
    public ArrayList getAllfilesOfOneFolder(int myFatherFATNumber){
        ArrayList allfiles = new ArrayList();
        int i;
        for(i=0;i<this.myfat.length;i++){
            FATStructure temp = this.myfat[i];
               if(temp.getFatType() == DataAttribute.FAT_aFolder){
                   if(((MyFolder)(temp.getFatContent())).getMyfatherFATNumber() == myFatherFATNumber)
                        allfiles.add(temp);
               }
               if(temp.getFatType() == DataAttribute.FAT_aFile){
                   if(((MyFile)(temp.getFatContent())).getMyfatherFATNumber() == myFatherFATNumber)
                        allfiles.add(temp);
               }
       }
        return allfiles;
    }
    
    public FATStructure getTheFile(int myFATNumber){
        if(myFATNumber>=0&&myFATNumber<=myfat.length)
            return myfat[myFATNumber];
        else
            return null;
    }
    //用于 程序测试
    //显示 某文件夹下的所有文件（文件夹及普通文件）
    public void showAllfilesOfOneFolder(int myFatherFATNumber){
        ArrayList allfiles = this.getAllfilesOfOneFolder(myFatherFATNumber);
        for(int i=0;i<allfiles.size();i++){
            FATStructure temp = (FATStructure)allfiles.get(i);
            if(temp.getFatType()== DataAttribute.FAT_aFolder){
                System.out.println(this.showFolder(((MyFolder)temp.getFatContent()).getMyFATNumber()));
            }else if(temp.getFatType()== DataAttribute.FAT_aFile){
                System.out.println(this.showFile(((MyFile)temp.getFatContent()).getMyFATNumber()));
            }
        }
    }

    //用于 程序测试
    //显示 某个文件分配表项 所对应的内容
    public String showFolder(int myFATNumber){
        MyFolder temp;
        String result = new String();
        if(this.myfat[myFATNumber].getFatIndex()!=DataAttribute.FAT_numberOfusable){
            if(this.myfat[myFATNumber].getFatType() == DataAttribute.FAT_aFolder){
                temp = (MyFolder)this.myfat[myFATNumber].getFatContent();
                result = result + temp.getMyfatherFATNumber() + "\n";
                result = result + temp.getMyFATNumber() + "\n";
                result = result + temp.getMyfolderAttributes().getFolderName() + "\n";
                result = result + temp.getMyfolderAttributes().getFolderLocation() + "\n";
                result = result + temp.getMyfolderAttributes().getFolderType() + "\n";
                result = result + temp.getMyfolderAttributes().getFolderCreatedTime().toString() + "\n";
            }
        }
        return result;
    }

    public FATStructure[] getMyFAT(){
        return this.myfat;
    }
}
